package com.uduemc.biso.node.web.api.service.impl;

import java.io.IOException;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.core.extities.center.Host;
import com.uduemc.biso.core.utils.RestResult;
import com.uduemc.biso.node.core.dto.FeignHBackupFindByHostIdTypeAndBetweenCreateAt;
import com.uduemc.biso.node.core.entities.HBackup;
import com.uduemc.biso.node.core.entities.HBackupSetup;
import com.uduemc.biso.node.core.feign.HBackupFeign;
import com.uduemc.biso.node.core.property.GlobalProperties;
import com.uduemc.biso.node.core.utils.RestResultUtil;
import com.uduemc.biso.node.core.utils.SitePathUtil;
import com.uduemc.biso.node.web.api.service.HBackupService;
import com.uduemc.biso.node.web.api.service.HostService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;

@Service
public class HBackupServiceImpl implements HBackupService {

	@Autowired
	private HBackupFeign hBackupFeign;

	@Autowired
	private GlobalProperties globalProperties;

	@Autowired
	private HostService hostServiceImpl;

	@Override
	public HBackup insert(HBackup hBackup) throws IOException {
		RestResult restResult = hBackupFeign.insert(hBackup);
		HBackup data = RestResultUtil.data(restResult, HBackup.class);
		return data;
	}

	@Override
	public HBackup findByHostIdAndId(long id, long hostId) throws IOException {
		RestResult restResult = hBackupFeign.findByHostIdAndId(id, hostId);
		HBackup data = RestResultUtil.data(restResult, HBackup.class);
		return data;
	}

	@Override
	public HBackup updateByPrimaryKey(HBackup hBackup) throws IOException {
		RestResult restResult = hBackupFeign.updateByPrimaryKey(hBackup);
		HBackup data = RestResultUtil.data(restResult, HBackup.class);
		return data;
	}

	@Override
	public PageInfo<HBackup> findNotDelPageInfoAll(long hostId, String filename, short type, int pageNum, int pageSize) throws IOException {
		RestResult restResult = hBackupFeign.findNotDelPageInfoAll(hostId, filename, type, pageNum, pageSize);
		@SuppressWarnings("unchecked")
		PageInfo<HBackup> data = (PageInfo<HBackup>) RestResultUtil.data(restResult, new TypeReference<PageInfo<HBackup>>() {
		});
		return data;
	}

	@Override
	public PageInfo<HBackup> findOKPageInfoAll(long hostId, String filename, short type, int pageNum, int pageSize) throws IOException {
		RestResult restResult = hBackupFeign.findOKPageInfoAll(hostId, filename, type, pageNum, pageSize);
		@SuppressWarnings("unchecked")
		PageInfo<HBackup> data = (PageInfo<HBackup>) RestResultUtil.data(restResult, new TypeReference<PageInfo<HBackup>>() {
		});
		return data;
	}

	@Override
	public PageInfo<HBackup> findPageInfoAll(long hostId, String filename, short type, int pageNum, int pageSize) throws IOException {
		RestResult restResult = hBackupFeign.findPageInfoAll(hostId, filename, type, pageNum, pageSize);
		@SuppressWarnings("unchecked")
		PageInfo<HBackup> data = (PageInfo<HBackup>) RestResultUtil.data(restResult, new TypeReference<PageInfo<HBackup>>() {
		});
		return data;
	}

	@Override
	public List<HBackup> recentMonth(long hostId, short type) throws IOException {
		FeignHBackupFindByHostIdTypeAndBetweenCreateAt feignParam = new FeignHBackupFindByHostIdTypeAndBetweenCreateAt();
		feignParam.setHostId(hostId).setType(type);

		DateTime offsetMonth = DateUtil.offsetMonth(DateUtil.date(), -1);
		DateTime start = DateUtil.date(offsetMonth.toLocalDateTime().toLocalDate());
		DateTime end = DateUtil.date(DateUtil.offsetDay(DateUtil.date(), 1).toLocalDateTime().toLocalDate());
		feignParam.setStart(start.toJdkDate()).setEnd(end.toJdkDate());

		RestResult restResult = hBackupFeign.findByHostIdTypeAndBetweenCreateAt(feignParam);
		@SuppressWarnings("unchecked")
		List<HBackup> data = (ArrayList<HBackup>) RestResultUtil.data(restResult, new TypeReference<ArrayList<HBackup>>() {
		});
		return data;
	}

	@Override
	public List<HBackup> recentWeek(long hostId, short type) throws IOException {
		FeignHBackupFindByHostIdTypeAndBetweenCreateAt feignParam = new FeignHBackupFindByHostIdTypeAndBetweenCreateAt();
		feignParam.setHostId(hostId).setType(type);

		DateTime lastWeek = DateUtil.lastWeek();
		DateTime start = DateUtil.date(lastWeek.toLocalDateTime().toLocalDate());
		DateTime end = DateUtil.date(DateUtil.offsetDay(DateUtil.date(), 1).toLocalDateTime().toLocalDate());
		feignParam.setStart(start.toJdkDate()).setEnd(end.toJdkDate());

		RestResult restResult = hBackupFeign.findByHostIdTypeAndBetweenCreateAt(feignParam);
		@SuppressWarnings("unchecked")
		List<HBackup> data = (ArrayList<HBackup>) RestResultUtil.data(restResult, new TypeReference<ArrayList<HBackup>>() {
		});
		return data;
	}

	@Override
	public List<HBackup> filterByDay(long hostId, short type, LocalDate localDate) throws IOException {
		FeignHBackupFindByHostIdTypeAndBetweenCreateAt feignParam = new FeignHBackupFindByHostIdTypeAndBetweenCreateAt();
		feignParam.setHostId(hostId).setType(type);

		DateTime start = DateUtil.date(localDate);
		DateTime end = DateUtil.date(DateUtil.offsetDay(DateUtil.date(localDate), 1).toLocalDateTime().toLocalDate());
		feignParam.setStart(start.toJdkDate()).setEnd(end.toJdkDate());

		RestResult restResult = hBackupFeign.findByHostIdTypeAndBetweenCreateAt(feignParam);
		@SuppressWarnings("unchecked")
		List<HBackup> data = (ArrayList<HBackup>) RestResultUtil.data(restResult, new TypeReference<ArrayList<HBackup>>() {
		});
		return data;
	}

	@Override
	public HBackup delete(Host host, HBackup hBackup) throws IOException {
		hBackup.setStatus((short) 4);
		HBackup update = updateByPrimaryKey(hBackup);
		if (update == null) {
			return null;
		}

		// 创建临时备份的目录
		String basePath = globalProperties.getSite().getBasePath();
		String absoluteHBackupZipPath = SitePathUtil.getUserHBackupZipPath(host, basePath, hBackup);

		if (FileUtil.isFile(absoluteHBackupZipPath)) {
			FileUtil.del(absoluteHBackupZipPath);
		}

		return update;
	}

	@Override
	public void deleteExtraAutoBackupData(HBackupSetup hBackupSetup) throws IOException {
		Long hostId = hBackupSetup.getHostId();
		Short type = hBackupSetup.getType();
		Integer retain = hBackupSetup.getRetain();

		Host host = hostServiceImpl.getInfoById(hostId);
		if (host == null) {
			return;
		}

		type = type == null ? 0 : type.shortValue();
		if (type < 1 || type > 3) {
			return;
		}

		retain = retain == null ? 0 : retain.intValue();
		if (retain < 1) {
			return;
		}

		RestResult restResult = hBackupFeign.findByHostIdType(hostId, (short) 1);
		@SuppressWarnings("unchecked")
		List<HBackup> list = (ArrayList<HBackup>) RestResultUtil.data(restResult, new TypeReference<ArrayList<HBackup>>() {
		});

		if (CollUtil.isEmpty(list)) {
			return;
		}

		int size = list.size();
		if (size <= retain) {
			return;
		}

		for (int i = retain; i < size; i++) {
			HBackup hBackup = list.get(i);
			delete(host, hBackup);
		}
	}

	@Override
	public int totalByHostIdFilenameAndType(long hostId, String filename, short type) throws IOException {
		RestResult restResult = hBackupFeign.totalByHostIdFilenameAndType(hostId, filename, type);
		Integer data = RestResultUtil.data(restResult, Integer.class);
		return data == null ? 0 : data.intValue();
	}
}
